<?php

/**
 * Created by PhpStorm.
 * User: apple
 * Date: 2018/11/23
 * Time: 12:26 PM
 */
use weworkapi\api\src\CorpAPI;
import('weworkapi.api.src.CorpApp', EXTEND_PATH,'.php');
class CrmController
{
    public $qiyeweixin = null;
    public function __construct()
    {
        $this->accessControl();
        $this->optionsRequestHandle();
        $config = config('qiyeweixin');
        $this->qiyeweixin =  new CorpAPI($config['CORP_ID'], $config['CONTACT_SYNC_SECRET']);


        //    // TODO sign验证

        //    if (in_array(request()->action(), $this->postMethods())) {
        //        $this->postRequestCheck();
        //    }

        //    if (!in_array(request()->action(), $this->noVerifyToken())) {
        //        $this->verifyToken();
        //    }

        //    \think\Cache::connect([
        //        'type' => 'memcache',
        //        'prefix' => 'purchase',
        //    ]);
    }

    /**
     * 签名验证
     * 签名规则：
     *   参数字典排序
     *   参数转成queryString字符串
     *   拼接 'key=$key'
     *   md5加密
     */
    protected function sign($params, $key)
    {
        ksort($params);
        $string = '';
        foreach ($params as $k => $v) {
            $string .= $k . '=' . $v . '&';
        }
        $string .= "key={$key}";
        return  md5($string);
    }

    /**
     * 登录后生成token
     * 生成规则：
     *   用户ID 10进制转为16进制 (8位)
     *   平台 16进制1-15 1位
     *   当前平台账号登录
     *   时间戳 + 随机数  md5后 前24位
     */
    protected function generateToken()
    {
        $string = time() . mt_rand(1000000000, 9999999999);
        $string = md5($string);

        return strtoupper($string);
    }

    protected function verifyToken()
    {
        $request = request();
        $userId = $request->header('userId');
        $platform = $request->header('platform');
        $token = $request->header('token');

        if (! $userId || ! $token) $this->serverErrorTerminate('没有提交用户令牌信息');

        $tokenKey = 'token';
        $lastLoginKey = 'last_login';

        if (in_array($platform, config('platform'))) {
            $tokenKey .= "_{$platform}";
            $lastLoginKey .= "_{$platform}";
        }

        $userModel = new \app\purchase\model\Client();
        $user = $userModel->where('client_id', $userId)->find();
        if ($user->$tokenKey !== $token) $this->serverErrorTerminate('用户令牌验证失败');

        // TODO 使用redis比较最后一次请求的时间 而非最后登录时间
        if ($user->getData($lastLoginKey) + 1800 < time()) $this->serverErrorTerminate('用户令牌已经失效', 1010);

        // TODO 将用户数据放入全局缓存redis


        // 刷新最后登录时间
        $userModel->save([
            $lastLoginKey => time(),
        ], [
            'client_id' => $userId
        ]);
    }


    /**
     * 生成签名密钥
     * key属于token
     * 生成规则：
     *   时间戳 + 随机数
     *   md5后32位 取后31位
     *   转大写 按8-4-4-4-12分割
     */
    protected function generateKey()
    {
        $string = time() . mt_rand(1000000000, 9999999999);
        $string = md5($string);
        $string = strtoupper($string);
        $lengthArr = [8, 4, 4, 4, 12];
        $stringA = '';
        foreach ($lengthArr as $len) {
            $stringA .= substr($string, 0, $len) . '-';
            $string = substr($string, $len - 1);
        }
        return rtrim($stringA, '-');
    }


    /**
     * options类型的预请求直接返回
     */
    private function optionsRequestHandle()
    {
        if ( request()->isOptions() ) {
            \think\Response::create()->send();
            die();
        }
    }

    /**
     * 跨域设置
     * 前面不能有任何输出
     */
    private function accessControl()
    {
        \think\Hook::add('response_send', function($response) {
            $response->header([
                'Access-Control-Allow-Origin' => '*',
                'Access-Control-Allow-Headers' => '*',
            ]);
        });
    }

    /**
     * 模板方法
     * 子类中实现哪些方法必须为post方式请求
     * @return array
     */
    protected function postMethods()
    {
        return [];
    }


    protected function noVerifyToken()
    {
        return [];
    }



    /**
     * post请求检测
     */
    protected function postRequestCheck()
    {
        if ( ! request()->isPost() ) {
            json([
                'code' => 1001,
                'message' => '请求方式错误',
                'data' => [],
            ])->send();
            die();
        }

    }

    /**
     * 服务器内容错误终止
     */
    protected function serverErrorTerminate($msg = '', $code = 1003)
    {
        json([
            'code' => $code,
            'message' => $msg ?: '服务器内部错误',
            'data' => [],
        ])->send();
        die();
    }

    /**
     * 成功后返回
     * @param array $data
     * @param string $msg
     */
    protected function successTerminate($data = [], $msg = '')
    {
        json([
            'code' => 200,
            'message' => $msg ?: 'success',
            'data' => $data,
        ])->send();
        die();
    }

    protected function cacheFirst($cacheKey, $callback, $flush = false, ...$params)
    {
//        dump(array_slice(func_get_args(), 3));
        $flush = true;

        if (! $flush) {
            $result = \think\Cache::get($cacheKey);
            if (!empty($result)) return $result;
        }
        $result = call_user_func_array($callback, $params);
        \think\Cache::set($cacheKey, $result);
        return $result;
    }
}